package DAO;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


import connection.ConnectionManager;
import java.sql.Connection;
import java.sql.PreparedStatement;

import modelo.Cliente;
import modelo.Estadio;
import modelo.Funcionario;
import modelo.Venda;
import modelo.VendaIngresso;

public class VendaDAOImp implements VendaDAO {

	/**
	 *  id_venda, vendaIngresso, data,funcionario, cliente, preco,quantidade
	 */
	
		private final String INSERT = "INSERT INTO Venda(id_vend_ingr, data_venda,id_funcionario, id_cliente, preco,quantidade) VALUES (?,?,?,?,?,?)";
		private final String UPDATE = "UPDATE Venda SET id_vend_ingr = ?, data_venda = ?,id_funcionario = ?, id_cliente = ?, preco = ?,quantidade = ? WHERE id_venda = ?";
		private final String DELETE = "DELETE from Venda WHERE id_venda = ?";
		private final String ALL = "SELECT * FROM Venda";
		private final String ID = "SELECT * FROM Venda where id_venda = ?";
		private final String FINAL = "SELECT * FROM Venda order by id_venda desc limit 1";

		private ConnectionManager connectionManager;
		private static Connection connection;

		VendaDAOImp() {
			this.openConnection();
		}

		public boolean isConnectionClose() {
			try {
				return connection.isClosed();
			} catch (SQLException ex) {
				return false;
			}
		}

		public Venda salvar(Venda e) {
			PreparedStatement ps = null;
			try {
				// 2 crie uma instancia de PreparedStatement
				// passe para ela a instrucao para realizar alteracoes em uma
				// registro do banco
				ps = connection.prepareStatement(INSERT);
				/**
				 *  id_venda, vendaIngresso, data,funcionario, cliente, preco,quantidade
				 */

				ps.setObject(1, e.getVendaIngresso().getIdVendaIngresso());
				ps.setObject(2, e.getData());
				ps.setObject(3, e.getFuncionario().getId());
				ps.setObject(4, e.getCliente().getId());
				ps.setObject(5, e.getPreco());
				ps.setObject(6, e.getQuantidade());
				
				ps.executeUpdate();

			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}
			return e;

		}

		@Override
		public void alterar(Venda e) {
			PreparedStatement ps = null;
			try {
				// 2 crie uma instancia de PreparedStatement
				// passe para ela a instrucao para realizar alteracoes em uma
				// registro do banco
				ps = connection.prepareStatement(UPDATE);
				/**
				 *  id_venda, vendaIngresso, data,funcionario, cliente, preco,quantidade
				 */
				
				ps.setObject(1, e.getVendaIngresso().getIdVendaIngresso());
				ps.setObject(2, e.getData());
				ps.setObject(3, e.getFuncionario().getId());
				ps.setObject(4, e.getCliente().getId());
				ps.setObject(5, e.getPreco());
				ps.setObject(6, e.getQuantidade());
				ps.setObject(7, e.getIdVenda());
				ps.executeUpdate();

			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}

		}

		@Override
		public void deletar(Venda e) {
			try {
				PreparedStatement ps = null;
				ps = connection.prepareStatement(DELETE);
				// 3 passe para o PreparedStatement o valor do id que deve ser
				// excluido do banco de dados
				ps.setObject(1, e.getIdVenda());

				ps.executeUpdate();

			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}

		}

		@Override
		public List<Venda> findAll() {
			List<Venda> vendas = new ArrayList<Venda>();
			List<Estadio> estadios = new ArrayList<Estadio>();
			List<VendaIngresso> vendaIngressos = new ArrayList<VendaIngresso>();
			List<Cliente> clientes = new ArrayList<Cliente>();
			List<Funcionario> funcionarios = new ArrayList<Funcionario>();
			
			EstadioDAO estadio = DAOFactory.getEstadioDAO();
			ClienteDAO clienteDAO =DAOFactory.getClienteDAO();
			FuncionarioDAO funcionarioDAO = DAOFactory.getFuncionarioDAO();
			VendaIngressoDAO vendaIngressoDAO = DAOFactory.getVendaIngressoDAO();
			
			try {
				PreparedStatement ps = null;
				ResultSet rs = null;
				ps = connection.prepareStatement(ALL);

				// 4 Obtenha uma instancia de resultset
				rs = ps.executeQuery();
				/**
				 *  id_venda, vendaIngresso, data,funcionario, cliente, preco,quantidade
				 */
				while (rs.next()) {
					Venda venda = new Venda();
					VendaIngresso vendaIngresso = new VendaIngresso();
					vendaIngresso.setIdVendaIngresso(rs.getInt("id_vend_ingr"));
					vendaIngressos = vendaIngressoDAO.buscaVendaIngressoPorId(vendaIngresso);
					venda.setVendaIngresso(vendaIngressos.get(0));
					venda.setIdVenda(rs.getInt("id_venda"));
					estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));
					Cliente cliente = new Cliente();
					cliente.setId(rs.getInt("id_cliente"));
					clientes = clienteDAO.buscaClientePorId(cliente);
					venda.setCliente(clientes.get(0));
					Funcionario funcionario = new Funcionario();
					funcionario.setId(rs.getInt("id_funcionario"));
					funcionarios = funcionarioDAO.buscaFuncionarioPorId(funcionario);
					venda.setFuncionario(funcionarios.get(0));
					venda.setData(rs.getDate("data"));
					venda.setPreco(rs.getDouble("preco"));
					venda.setQuantidade(rs.getInt("quantidade"));
					vendas.add(venda);
					// 5 crie uma instancia de cidade com os dados
					// obtidos do banco e adicione a lista de cidadesf

				}

			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}
			return vendas;
		}

		@Override
		public void openConnection() {
			if (connectionManager == null) {
				connectionManager = ConnectionManager.getInstance();
			}

			if (connection == null) {
				connection = connectionManager.getConnection();
			}

			if (isConnectionClose()) {
				connection = connectionManager.getConnection();
			}

		}

		@Override
		public void closeConnection() {
			if (connection != null && connectionManager != null) {
				if (!this.isConnectionClose()) {
					connectionManager.closeConnection(connection);
				}
			}

		}



		@Override
		public List<Venda> buscarVendaPorId(Venda venda) {
			List<Venda> vendas = new ArrayList<Venda>();
			List<Estadio> estadios = new ArrayList<Estadio>();
			List<Cliente> clientes = new ArrayList<Cliente>();
			List<Funcionario> funcionarios = new ArrayList<Funcionario>();
			
			EstadioDAO estadio = DAOFactory.getEstadioDAO();
			ClienteDAO clienteDAO =DAOFactory.getClienteDAO();
			FuncionarioDAO funcionarioDAO = DAOFactory.getFuncionarioDAO();
			VendaIngressoDAO vendaIngressoDAO = DAOFactory.getVendaIngressoDAO();

			try {
				
				PreparedStatement ps = null;
				ResultSet rs = null;
				
				ps = connection.prepareStatement(ID);
				// 6 informe o parmetro para instrucao ID
				ps.setObject(1, venda.getIdVenda());
				rs = ps.executeQuery();

				while (rs.next()) {
					
					venda.setIdVenda(rs.getInt("id_venda"));
					//estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));
					Cliente cliente = new Cliente();
					VendaIngresso vendaIngresso = new VendaIngresso();
					vendaIngresso.setIdVendaIngresso(rs.getInt("id_vend_ingr"));
					List<VendaIngresso> vendasIng = vendaIngressoDAO.buscaVendaIngressoPorId(vendaIngresso); 
					if (vendasIng.isEmpty()) {
						venda.setVendaIngresso(null);
					} else {
						venda.setVendaIngresso(vendasIng.get(0));
					}
					cliente.setId(rs.getInt("id_cliente"));
					clientes = clienteDAO.buscaClientePorId(cliente);
					Funcionario funcionario = new Funcionario();
					funcionario.setId(rs.getInt("id_funcionario"));
					funcionarios = funcionarioDAO.buscaFuncionarioPorId(funcionario);
					venda.setData(rs.getDate("data_venda"));
					venda.setPreco(rs.getDouble("preco"));
					venda.setQuantidade(rs.getInt("quantidade"));
					vendas.add(venda);
					// 5 crie uma instancia de cidade com os dados
					// obtidos do banco e adicione a lista de cidadesf

				}
			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}
			return vendas;
		}

		public List<Venda> buscarVendaPorFinal(Venda venda) {
			List<Venda> vendas = new ArrayList<Venda>();
			List<Estadio> estadios = new ArrayList<Estadio>();
			List<Cliente> clientes = new ArrayList<Cliente>();
			List<Funcionario> funcionarios = new ArrayList<Funcionario>();
			
			EstadioDAO estadio = DAOFactory.getEstadioDAO();
			ClienteDAO clienteDAO =DAOFactory.getClienteDAO();
			FuncionarioDAO funcionarioDAO = DAOFactory.getFuncionarioDAO();
			VendaIngressoDAO vendaIngressoDAO = DAOFactory.getVendaIngressoDAO();

			PreparedStatement ps = null;
			ResultSet rs = null;

			try {
				
				ps = connection.prepareStatement(FINAL);
				// 6 informe o parmetro para instrucao ID
				rs = ps.executeQuery();

				while (rs.next()) {
					
					venda.setIdVenda(rs.getInt("id_venda"));
					//estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));
					Cliente cliente = new Cliente();
					VendaIngresso vendaIngresso = new VendaIngresso();
					vendaIngresso.setIdVendaIngresso(rs.getInt("id_vend_ingr"));
					List<VendaIngresso> vendasIng = vendaIngressoDAO.buscaVendaIngressoPorId(vendaIngresso); 
					if (vendasIng.isEmpty()) {
						venda.setVendaIngresso(null);
					} else {
						venda.setVendaIngresso(vendasIng.get(0));
					}
					cliente.setId(rs.getInt("id_cliente"));
					clientes = clienteDAO.buscaClientePorId(cliente);
					Funcionario funcionario = new Funcionario();
					funcionario.setId(rs.getInt("id_funcionario"));
					funcionarios = funcionarioDAO.buscaFuncionarioPorId(funcionario);
					venda.setData(rs.getDate("data_venda"));
					venda.setPreco(rs.getDouble("preco"));
					venda.setQuantidade(rs.getInt("quantidade"));
					vendas.add(venda);
					// 5 crie uma instancia de cidade com os dados
					// obtidos do banco e adicione a lista de cidadesf

				}
			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				//this.closeConnection();
			}
			return vendas;
		}
		
		public List<Venda> buscarVendaPorId2(Venda venda) {
			List<Venda> vendas = new ArrayList<Venda>();
			List<Estadio> estadios = new ArrayList<Estadio>();
			List<Cliente> clientes = new ArrayList<Cliente>();
			List<Funcionario> funcionarios = new ArrayList<Funcionario>();
			
			EstadioDAO estadio = DAOFactory.getEstadioDAO();
			ClienteDAO clienteDAO =DAOFactory.getClienteDAO();
			FuncionarioDAO funcionarioDAO = DAOFactory.getFuncionarioDAO();
			VendaIngressoDAO vendaIngressoDAO = DAOFactory.getVendaIngressoDAO();

			try {
				
				PreparedStatement ps = null;
				ResultSet rs = null;
				
				ps = connection.prepareStatement(ID);
				// 6 informe o parmetro para instrucao ID
				ps.setObject(1, venda.getIdVenda());
				rs = ps.executeQuery();

				while (rs.next()) {
					
					venda.setIdVenda(rs.getInt("id_venda"));
					//estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));
					Cliente cliente = new Cliente();
					
						venda.setVendaIngresso(null);
					
					cliente.setId(rs.getInt("id_cliente"));
					clientes = clienteDAO.buscaClientePorId(cliente);
					Funcionario funcionario = new Funcionario();
					funcionario.setId(rs.getInt("id_funcionario"));
					funcionarios = funcionarioDAO.buscaFuncionarioPorId(funcionario);
					venda.setData(rs.getDate("data_venda"));
					venda.setPreco(rs.getDouble("preco"));
					venda.setQuantidade(rs.getInt("quantidade"));
					vendas.add(venda);
					// 5 crie uma instancia de cidade com os dados
					// obtidos do banco e adicione a lista de cidadesf

				}
			} catch (SQLException ex) {
				Logger.getLogger(VendaDAOImp.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				this.closeConnection();
			}
			return vendas;
		}
	

}
